/*
 * PhoneSynchronizer.java
 *
 * Created on February 5, 2009, 3:48 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package com.vacuela.phonecredits;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlImageInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.vacuela.phonecredits.util.SynchUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

/**
 *
 * @author nestor.carrasco
 */
public class PhoneSynchronizerJob implements Job {

    private final static Object MONITOR = new Object();
    private SynchUtils syn = null;
    protected final Log log = LogFactory.getLog(PhoneSynchronizerJob.class);
    private static final BrowserVersion[] versionList =
            new BrowserVersion[]{BrowserVersion.INTERNET_EXPLORER_6,
        BrowserVersion.FIREFOX_3,
        BrowserVersion.INTERNET_EXPLORER_7};
    private static boolean isRunning = false;

    /** Creates a new instance of PhoneSynchronizer */
    public PhoneSynchronizerJob() {
    }

    public static boolean isRunning() {
        return isRunning;
    }

    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Date startDate = new Date();
        isRunning = true;
        log.info("Start Synchonizer Job=> " + startDate);
        synchronized (MONITOR) {
            try {
                syn = (SynchUtils) jobExecutionContext.getScheduler().getContext().get("utilClass");
                syn.openConnection();
                Pattern patronFecha = Pattern.compile("(\\d{2}/\\d{2}/\\d{4})");
                Pattern patronHora = Pattern.compile("\\d{2}:\\d{2}:\\d{2}");
                //Pattern patronSaldos = Pattern.compile("fono: (\\$\\s(\\d)+\\.\\d{2})|null");
                Matcher match = null;
                int browserSelected = (int) (startDate.getTime() % 3);

                Map<String, String> phonesMap = syn.loadMap("getPhonesQry");
                WebClient webClient = null;
                //Validating if there is any Proxy
                if ("TRUE".equalsIgnoreCase(syn.getConfigParam("proxyEnabled"))) {
                    webClient = new WebClient(versionList[browserSelected], syn.getConfigParam("proxyIP"), syn.getIntConfigParam("proxyPort"));
                } else {
                    webClient = new WebClient(versionList[browserSelected]);
                }
                //Disable the JavaScript in the Response
                webClient.setJavaScriptEnabled(false);
                // Enable the Redirect response/ Meta Data
                webClient.setRedirectEnabled(true);
                webClient.setTimeout(120000);

                for (Entry<String, String> entry : phonesMap.entrySet()) {
                    String hora = "00:00:00";
                    String fecha = "01/01/1900";
                    float saldo = -3.0f;//En caso de que no sea correcto el tel o sim


                    // URL Login
                    try {
                        final HtmlPage page = webClient.getPage(syn.getConfigParam("urlLogin"));
                        HtmlForm loginForm = page.getFormByName(syn.getConfigParam("fromName"));
                        final HtmlTextInput telefonoField = loginForm.getInputByName(syn.getConfigParam("phoneParameterName"));
                        final HtmlPasswordInput nipField = loginForm.getInputByName(syn.getConfigParam("nipParameterName"));
                        final HtmlImageInput button = loginForm.getInputByName("enviar");

                        telefonoField.setValueAttribute(entry.getKey());
                        nipField.setValueAttribute(entry.getValue());
                        HtmlPage mainPage = (HtmlPage) button.click();

                        log.info("===================================================");
                        log.info("Validating ::: " + entry.getKey() + " - " + entry.getValue());
                        List<FrameWindow> listFrame = mainPage.getFrames();

                        if (listFrame == null || listFrame.size() == 0) {
                            continue;
                        }
                        FrameWindow frameMain = mainPage.getFrameByName("menu");
                        HtmlPage saldoPage = webClient.getPage(syn.getConfigParam("urlSaldo"));
                        String stringResponse = saldoPage.getWebResponse().getContentAsString();

                        //FECHA
                        match = patronFecha.matcher(stringResponse);
                        if (match.find()) {
                            fecha = match.group(0);
                        } else {
                            fecha = "01/01/1900";
                        }
                        log.info("Telcel Date ->>" + fecha);

                        //HORA
                        match = patronHora.matcher(stringResponse);
                        if (match.find()) {
                            hora = match.group(0);
                        } else {
                            hora = "00:00:00";
                        }
                        log.info("Telcel Time ->>" + hora);

                        //SALDOS
                        int index = stringResponse.indexOf(";fono: $ ");
                        int finish = stringResponse.substring(index).indexOf("</strong></font></div>");
                        String saldoStr1 = stringResponse.substring(index + 9, index + finish);
                        log.info("Saldo1 ->>" + saldoStr1);

                        index = stringResponse.indexOf("Saldo regalo : $ ");
                        finish = stringResponse.substring(index).indexOf("</strong></font></div>");
                        String saldoStr2 = stringResponse.substring(index + 17, index + finish);
                        log.info("Saldo2 ->>" + saldoStr2);

                        if (saldoStr1.equals("null")) {
                            saldo = -2;
                        } else {
                            saldo = Float.parseFloat(saldoStr1);
                            saldo += Float.parseFloat(saldoStr2);

                        }
                        webClient.getPage(syn.getConfigParam("urlLogOut"));
                        log.info("Logout of the Page");

                    } catch (Exception essss) {
                        saldo = -3;
                        log.error("Exception al Actualizar: " + entry.getKey(), essss);
                    }

                    log.info("Updating the Database");
                    syn.updateSaldoPhone(fecha, hora, saldo, entry.getKey());
                    log.info("===================================================");
                }//FOR

                EmailNotificationJob en = new EmailNotificationJob();
                en.execute(jobExecutionContext);

            } catch (Exception ex) {
                log.info("Exception PhoneSynchronizerJob =>" ,ex);
                //ex.printStackTrace();
            } finally {
                 syn.closeConnection();
            }
            log.info("Finish Job=> " + new Date());
            isRunning = false;
        }
    }

    public static void main(String[] args) {
        try {
            SchedulerFactory sf = new StdSchedulerFactory();
            Scheduler sched = sf.getScheduler();
            JobDetail jd = new JobDetail("JobTest", "group1", PhoneSynchronizerJob.class);


            long startTime = System.currentTimeMillis() + 3000L;
            SimpleTrigger simple = new SimpleTrigger("myTrigger",
                    "group2",
                    new Date(startTime),
                    new Date(startTime + (1000 * 60 * 1)),
                    0,
                    0L);
            SynchUtils syn = new SynchUtils();
            syn.openConnection();
            sched.scheduleJob(jd, simple);

            sched.getContext().put("utilClass", syn);
            sched.start();
        } catch (Exception ex) {
            LogFactory.getLog(PhoneSynchronizerJob.class).error("Exception=>>", ex);
        }

    }
}
